<!DOCTYPE html>
<html>
  
<head>
  <meta charset="utf-8">
  <meta name="author" content="饿包子" />
  
  
  <title>Three.js的学习笔记（一） | 饿包子博客</title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  
    <meta name="keywords" content="学习笔记," />
  

  
  <meta name="description" content="在最初接触Three.js的时候，我就被它所吸引，但一直没能好好学下去，国内的文档翻译又并不是很全面，在学习期间找了很多文章，不知道是不是时间的原因，文章基本上都没有相要的答案，只能一点一点啃官网文档，现在列出自己的学习过程，希望能够帮助到大家。基本上看完这篇你就能实现一个简单的3D机房">

  
  
    <link rel="icon" href="/blog/images/xian.ico">
    <link rel="apple-touch-icon" href="/blog/images/Logo.png">
  

  
<link rel="stylesheet" href="/blog/css/Awesome.min.css">


  
<link rel="stylesheet" href="/blog/css/index.css">
<link rel="stylesheet" href="/blog/styles/components/highlight/highlight.css">


  
  
<script src="/blog/common/jquery.min.js"></script>

  
    
<script src="/blog/common/Av.min.js"></script>

  

  
    
<script src="/blog/common/MathJax.js"></script>

  

  
    
<script src="/blog/common/Valine.min.js"></script>

  

  

  <script>
  // theme-ad's config script
  // it can be used in every script
  
  window.AD_CONFIG = {
    leancloud: {"appid":"gE1EosDsVgB2slV4E92yPkcG-gzGzoHsz","appkey":"niR787UVTMyJQrR6gmOiJCKe","comment":true,"count":true},
    welcome: {"enable":false,"interval":30},
    start_time: "2018-06-10",
    passwords: ["a621ab606db2a11f63edc576a729843b8269250dc324206871d90635ac5e531c", ],
    is_post: true,
    lock: false,
    author: "饿包子",
    share: {"twitter":false,"facebook":false,"weibo":true,"qq":true,"wechat":false},
    mathjax: true,
    page_type: "",
    root: "/blog/"
  };
</script>

  
<script src="/blog/vendor/sha256.min.js"></script>
<script src="/blog/js/auth.js"></script>
<script src="/blog/js/index.js"></script>
<script src="/blog/vendor/qrcode.min.js"></script>


<meta name="generator" content="Hexo 5.4.2"></head>
  <body>
    <header class="site-header">
  <div class="site-header-brand">
    
      <span class="site-header-brand-title">
        <a href="/blog/">清风逐月</a>
      </span>
    
    
      <span class="site-header-brand-motto"> | 我思故我在</span>
    
  </div>
  <div class="site-header-right">
    <nav class="site-header-navigation">
      
        <a href="/blog/" target="_self">主页</a>
      
        <a href="/blog/archives/" target="_self">归档</a>
      
        <a href="/blog/tags/" target="_self">标签</a>
      
        <a href="/blog/categories/" target="_self">分类</a>
      
        <a href="/blog/categories/%E6%97%A5%E8%AE%B0" target="_self">日记</a>
      
    </nav>
    <div class="site-header-btn">
      
        <a href="https://github.com/lixianbin1/" target="_blank" id="site-github">
          <i class="fa fa-github-alt"></i>
        </a>
      
      <a href="javascript:void(0);" id="site-search">
        <i class="fa fa-search"></i>
      </a>
      <a href="javascript:void(0);" id="site-nav-btn">
        <i class="fa fa-ellipsis-v"></i>
      </a>
    </div>
  </div>
</header>
<nav class="table-content" id="site-nav">
  <div class="table-content-title">
    <span>导航</span>
  </div>
  <div class="table-content-main">
    <ol class="toc">
      
        <li class="toc-item">
          <a href="/blog/" target="_self">
            主页
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/archives/" target="_self">
            归档
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/tags/" target="_self">
            标签
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/categories/" target="_self">
            分类
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/categories/%E6%97%A5%E8%AE%B0" target="_self">
            日记
          </a>
        </li>
      
    </ol>
  </div>
</nav>
<div id="site-process"></div>
    <main>
      
  <div class="passage">
  <div class="passage-meta">
    <span>
      <i class="fa fa-calendar"></i>2019-05-08
    </span>
    
      <span>
        | <a href="/blog/categories/%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/"><i class="fa fa-bookmark"></i>学习笔记</a>
      </span>
    
    
      <span>
        | <i class="fa fa-unlock-alt"></i>UNLOCK
      </span>
    
    <span>
       | <i class="fa fa-calendar"></i>更新时间:NaN-NaN-NaN NaN:NaN 
    </span>
  </div>
  <h1 class="passage-title">
    Three.js的学习笔记（一）
  </h1>
  
    <div class="passage-cover">
      <figure style="background-image:url(/blog/images/posts/1905091.png);"></figure>
    </div>
  
  <article class="passage-article">
    <h1 id="官网-https-threejs-org"><a href="#官网-https-threejs-org" class="headerlink" title="官网 https://threejs.org"></a>官网 <a target="_blank" rel="noopener" href="https://threejs.org/">https://threejs.org</a></h1><p>Three.js是一个Javascript库，所以当你使用它创建一个WebGl应用的时候，你所需要的仅仅是一个文本编辑器和一个支持WebGl的浏览器，但是国内对于Three.js的文档并不是很齐全，官网自身的中文翻译仅仅只是标题。</p>
<blockquote>
<p>文章中所展示的例子都是实际执行的代码，并没有展示各类API的详细信息</p>
</blockquote>
<h2 id="基本要素"><a href="#基本要素" class="headerlink" title="基本要素"></a>基本要素</h2><p>在使用Threejs 来显示一样东西或者什么的时候，你需要scene （场景），camera （相机）和 renderer（渲染器）来布置一个舞台来进行展示或者表演，下面的例子就是一个基本的场景，展示一个“ 空 ”的场景</p>
<blockquote>
<p>引入文件：three.min.js</p>
</blockquote>
<ul>
<li>这是最基本的引入文件，Three.js要执行的必需文件</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">//创建一个场景</span><br><span class="line">var scene = new THREE.Scene();</span><br><span class="line"></span><br><span class="line">//创建一个摄像机 属性:(视野,宽高比,近剪裁平面和远剪裁平面)</span><br><span class="line">var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );</span><br><span class="line"></span><br><span class="line">//创建渲染器实例 设置我们希望它渲染应用程序的大小，浏览器窗口的宽度和高度</span><br><span class="line">var renderer = new THREE.WebGLRenderer(&#123;</span><br><span class="line">    antialias:true, //开启抗锯齿效果</span><br><span class="line">    alpha:true //允许透明</span><br><span class="line">&#125;);</span><br><span class="line">    renderer.setClearColor(0xffffff);//设置场景颜色</span><br><span class="line">    renderer.setSize( window.innerWidth, window.innerHeight );</span><br><span class="line">    document.body.appendChild( renderer.domElement );</span><br><span class="line"></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line">//渲染</span><br><span class="line">renderer.render( scene, camera );</span><br></pre></td></tr></table></figure>

<h2 id="辅助对象"><a href="#辅助对象" class="headerlink" title="辅助对象"></a>辅助对象</h2><p>在开始开发的时候，你可能分不清XYZ轴的方向，光照的方向，阴影产生的方向，距离的多少等等，Three.js 当然提供了一些辅助对象，用于辅助开发，我在下例仅举几个简单例子，详细可以看后面的学习文章或者官方文档</p>
<blockquote>
<p>用于区分XYZ 轴的简单对象</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">//辅助对象 三维箭头 红x 绿y 蓝z </span><br><span class="line">var axesHelper = new THREE.AxesHelper( 50 ); //50 为长度</span><br><span class="line">    scene.add( axesHelper );</span><br></pre></td></tr></table></figure>

<blockquote>
<p>用于区分坐标的坐标格辅助对象</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">//坐标格辅助</span><br><span class="line">var grid = new THREE.GridHelper(80, 20, 0x000000, 0x000000);</span><br><span class="line">    grid.material.transparent = true;//允许透明</span><br><span class="line">    grid.material.opacity = 0.3; //透明度</span><br><span class="line">    grid.rotation.x = 0.5 * Math.PI;//x轴翻转90度</span><br><span class="line">    scene.add(grid);</span><br></pre></td></tr></table></figure>

<h2 id="光照和阴影"><a href="#光照和阴影" class="headerlink" title="光照和阴影"></a>光照和阴影</h2><p>在Three中，光照是很重要的一部分，在Three.js所渲染的世界中是没有光，如果在世界中不添加光，那么到处都是一片黑色，极致的黑会导致你什么都看见，有光就会产生阴影（无影灯那种另说）。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">//平行光</span><br><span class="line">var light = new THREE.DirectionalLight( 0xffffff, 0.8 );</span><br><span class="line">var lightC=40</span><br><span class="line">    light.position.set( 20, 40, 20 );</span><br><span class="line">    light.castShadow = true; //允许产生阴影</span><br><span class="line">    light.shadow.camera.left = - lightC;</span><br><span class="line">    light.shadow.camera.right = lightC;</span><br><span class="line">    light.shadow.camera.top = lightC;</span><br><span class="line">    light.shadow.camera.bottom = - lightC;</span><br><span class="line">    light.shadow.camera.near = 10;</span><br><span class="line">    light.shadow.camera.far = 180;</span><br><span class="line">    light.shadow.bias = - 0.001;</span><br><span class="line">    light.shadow.mapSize.width = 1512;</span><br><span class="line">    light.shadow.mapSize.height = 1512;</span><br><span class="line">    scene.add( light );</span><br></pre></td></tr></table></figure>
<h2 id="轨道控制相机"><a href="#轨道控制相机" class="headerlink" title="轨道控制相机"></a>轨道控制相机</h2><p>方便我们对模型进行360度的观察，官方提供的一个观察对象的相机，（当然，之前的我并没有注意到，结果自己写的一个，和官方的有点像，结果看到看到了官方的，总感觉自己白写了）基本可以说是完善的很丰富了，当然可能不是很符合我们的习惯，那么想改控制的方式，当然可以选择修改源码，Three.js的各类js并没有进行压缩，这给了我们很好的观察机会</p>
<blockquote>
<p>引入文件：OrbitControls.js</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">//轨道控制相机</span><br><span class="line">var controls = new THREE.OrbitControls( camera );</span><br><span class="line">    camera.position.set( 0, 20, 10 );</span><br><span class="line">    controls.enableDamping = true</span><br><span class="line">    controls.minPolarAngle= Math.PI/8;</span><br><span class="line">    controls.maxPolarAngle= Math.PI/3;</span><br><span class="line">    controls.panSpeed=0.1</span><br><span class="line">    controls.rotateSpeed=0.05</span><br><span class="line">    controls.maxZoom=10</span><br><span class="line">    controls.minDistance=50</span><br><span class="line">    controls.maxDistance=80</span><br><span class="line">    controls.dampingFactor=0.08</span><br><span class="line">    controls.update();</span><br><span class="line">    (function animate() &#123;</span><br><span class="line">      requestAnimationFrame( animate );</span><br><span class="line">      controls.update();</span><br><span class="line">      renderer.render( scene, camera );</span><br><span class="line">    &#125;)()</span><br></pre></td></tr></table></figure>

<h2 id="插入模型及贴图"><a href="#插入模型及贴图" class="headerlink" title="插入模型及贴图"></a>插入模型及贴图</h2><p>3D模型有很多种文件格式，每种格式都有不同的用途，各种功能和复杂程度，我们要根据载入模型的文件来选择需要的loaders，我使用的是OBJ的文件格式</p>
<blockquote>
<p>引入文件：OBJLoaderjs &amp; MTLLoader.js</p>
</blockquote>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">var mtlLoader = new THREE.MTLLoader()</span><br><span class="line">    mtlLoader.setPath( &#x27;obj/&#x27; )</span><br><span class="line">    mtlLoader.load( &#x27;server.mtl&#x27;,function ( materials ) &#123;</span><br><span class="line">      materials.preload();</span><br><span class="line">      var objLoader=new THREE.OBJLoader()</span><br><span class="line">          objLoader.setMaterials( materials )</span><br><span class="line">          objLoader.setPath( &#x27;obj/&#x27; )</span><br><span class="line">          objLoader.load(&#x27;server.obj&#x27;,function(object)&#123;</span><br><span class="line">            scene.add( object );</span><br><span class="line">          &#125;,undefined,function(error)&#123;</span><br><span class="line">            console.log(error)</span><br><span class="line">          &#125;);</span><br><span class="line">    &#125;);</span><br><span class="line">...</span><br></pre></td></tr></table></figure>

<h2 id="设置动画及重绘"><a href="#设置动画及重绘" class="headerlink" title="设置动画及重绘"></a>设置动画及重绘</h2><p>在three.js动画系统中，您可以为模型的各种属性设置动画： SkinnedMesh（蒙皮和装配模型）的骨骼，Geometry.morphTargets（变形目标）， 不同的材料属性（颜色，不透明度，布尔运算），可见性和变换。动画属性可以淡入、淡出、交叉淡化和扭曲。</p>
<blockquote>
<p>定时重绘</p>
</blockquote>
<p>当我们需要一个简单的动画，定时就成了我们的选择，setInterval 或者 requestAnimationFrame 就能带给我们一个简单的动画，文档推荐 requestAnimationFrame：与 setInterval 相比，requestAnimationFrame 最大的优势是由系统来决定回调函数的执行时机</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">var animate = function () &#123;</span><br><span class="line">  requestAnimationFrame( animate );</span><br><span class="line">  cube.rotation.x += 0.01;</span><br><span class="line">  cube.rotation.y += 0.01;</span><br><span class="line">  renderer.render( scene, camera );</span><br><span class="line">&#125;;</span><br><span class="line">animate();</span><br></pre></td></tr></table></figure>

<h2 id="点击及交互"><a href="#点击及交互" class="headerlink" title="点击及交互"></a>点击及交互</h2><p>光线投射器（Raycaster）,该类用来处理光线投射。光线投射主要用于物体选择、碰撞检测以及图像成像等方面</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">var raycaster = new THREE.Raycaster();</span><br><span class="line">var mouse = new THREE.Vector2();</span><br><span class="line">function onMouseClick( event ) &#123;</span><br><span class="line">  // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)</span><br><span class="line">  mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;</span><br><span class="line">  mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;</span><br><span class="line">  render()</span><br><span class="line">&#125;</span><br><span class="line">function render() &#123;</span><br><span class="line">  //通过摄像机和鼠标位置更新射线</span><br><span class="line">  raycaster.setFromCamera( mouse, camera );</span><br><span class="line">  // 计算物体和射线的焦点</span><br><span class="line">  var intersects = raycaster.intersectObjects( scene.children );</span><br><span class="line">  console.log(intersects)</span><br><span class="line">  for ( var i = 0; i &lt; intersects.length; i++ ) &#123;</span><br><span class="line">    intersects[ i ].object.material.color.set( 0xffff00 );</span><br><span class="line">  &#125;</span><br><span class="line">  renderer.render( scene, camera );</span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line">window.addEventListener( &#x27;click&#x27;, onMouseClick, false );</span><br></pre></td></tr></table></figure>


<h2 id="兼容性检查"><a href="#兼容性检查" class="headerlink" title="兼容性检查"></a>兼容性检查</h2><p>兼容性的问题当然有，即使这个问题变得越来越少，但某些设备或浏览器可能仍然不支持WebGL。以下方法允许您检查是否支持它并向用户显示消息（如果不支持）</p>
<blockquote>
<p>引入文件: WebGL.js</p>
</blockquote>
<ul>
<li>这是你执行WebGl的检测函数所需要的文件，当然你也可以选择不检测，选择权在你</li>
</ul>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">&lt;script&gt;</span><br><span class="line">if ( WEBGL.isWebGLAvailable() === false )&#123;</span><br><span class="line">  document.body.appendChild( WEBGL.getWebGLErrorMessage() );</span><br><span class="line">&#125;</span><br><span class="line">//如果不支持会打印出信息</span><br><span class="line">&lt;/script&gt;</span><br></pre></td></tr></table></figure>

<p>##注意事项</p>
<blockquote>
<p>在three.js文档中，并未声明DOCTYPE，如遇到声明后，出现滚动条及canvas大小的样式问题，则需要在设置样式 canvas{ vertical-align:bottom }</p>
</blockquote>
<h2 id="工具推荐"><a href="#工具推荐" class="headerlink" title="工具推荐"></a>工具推荐</h2><h3 id="Magicavoxel"><a href="#Magicavoxel" class="headerlink" title="Magicavoxel"></a>Magicavoxel</h3><p>Magicavoxel是一个由gltracy独立开发的轻量级体素编辑器,大小连1个G都没有的建模软件，基本功能齐全，操作简单，是不可多得的好软件，当然，因为大小的关系，你也不能要求过多</p>
  </article>
  <aside class="table-content" id="site-toc">
  <div class="table-content-title">
    <i class="fa fa-arrow-right fa-lg" id="site-toc-hide-btn"></i>
    <span>目录</span>
  </div>
  <div class="table-content-main">
    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%AE%98%E7%BD%91-https-threejs-org"><span class="toc-text">官网 https:&#x2F;&#x2F;threejs.org</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%9F%BA%E6%9C%AC%E8%A6%81%E7%B4%A0"><span class="toc-text">基本要素</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BE%85%E5%8A%A9%E5%AF%B9%E8%B1%A1"><span class="toc-text">辅助对象</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%89%E7%85%A7%E5%92%8C%E9%98%B4%E5%BD%B1"><span class="toc-text">光照和阴影</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%BD%A8%E9%81%93%E6%8E%A7%E5%88%B6%E7%9B%B8%E6%9C%BA"><span class="toc-text">轨道控制相机</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%8F%92%E5%85%A5%E6%A8%A1%E5%9E%8B%E5%8F%8A%E8%B4%B4%E5%9B%BE"><span class="toc-text">插入模型及贴图</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%AE%BE%E7%BD%AE%E5%8A%A8%E7%94%BB%E5%8F%8A%E9%87%8D%E7%BB%98"><span class="toc-text">设置动画及重绘</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%82%B9%E5%87%BB%E5%8F%8A%E4%BA%A4%E4%BA%92"><span class="toc-text">点击及交互</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%85%BC%E5%AE%B9%E6%80%A7%E6%A3%80%E6%9F%A5"><span class="toc-text">兼容性检查</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%B7%A5%E5%85%B7%E6%8E%A8%E8%8D%90"><span class="toc-text">工具推荐</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Magicavoxel"><span class="toc-text">Magicavoxel</span></a></li></ol></li></ol></li></ol>
  </div>
</aside>

  
  
    <aside class="passage-copyright">
      <div>本文作者: 饿包子</div>
      
        <div>
          原文链接: 
          <a href="" target="_blank">https://lixianbin1.github.io/blog/2019/05/08/Three-js%E7%9A%84%E5%AD%A6%E4%B9%A0%E8%BF%87%E7%A8%8B%EF%BC%88%E4%B8%80%EF%BC%89/</a>
        </div>
      
      <div>
        版权声明: 本博客所有文章除特别声明外, 均采用 <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> 许可协议. 转载请注明出处!
      </div>
    </aside>
  
  
</div>

    </main>
    
    
<div class="site-footer-wrapper">
<!--
  <div class="footer-top">
    <a class="left" href="/blog/2019/05/26/%E3%80%90%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E3%80%91ES6%E7%9A%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" data-enable="true">
      <i class="fa fa-arrow-left"></i>
    </a>
    <a class="right" href="/blog/2019/04/27/React-16-8-%E6%96%B0%E5%A2%9E%E7%89%B9%E6%80%A7-Hook/" data-enable="true">
      <i class="fa fa-arrow-right"></i>
    </a>
  </div>
-->
  <footer class="site-footer">
    
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">网站推荐</h5>
          
            <span class="site-footer-item">
              <a href="https://tympanus.net/codrops/" target="_blank">Codrops</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://taobaofed.org/" target="_blank">淘宝前端团队(FED)</a>
            </span>
          
        </div>
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">文档教程</h5>
          
            <span class="site-footer-item">
              <a href="https://es6.ruanyifeng.com/" target="_blank">ES6入门</a>
            </span>
          
            <span class="site-footer-item">
              <a href="https://developer.mozilla.org/zh-CN/docs/Web" target="_blank">MDN Web文档</a>
            </span>
          
        </div>
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">兴趣前沿</h5>
          
            <span class="site-footer-item">
              <a href="https://threejs.org/" target="_blank">threejs</a>
            </span>
          
            <span class="site-footer-item">
              <a href="https://github.com/justadudewhohacks/face-api.js" target="_blank">face-api</a>
            </span>
          
        </div>
      
    
    <div class="site-footer-info">
      <i class="fa fa-clock-o"></i> 本站已稳定运行<span id="site-time"></span>
    </div>
    
      <div class="site-footer-info">
        <i class="fa fa-paw"></i> 您是本站第 <span id="site-count"></span> 位访客
      </div>
    
    
      <div class="site-footer-info">
        <i class="fa fa-at"></i> Email: xianbin.me@qq.com
      </div>
    
<!--     <div class="site-footer-info">
      <i class="fa fa-copyright"></i> 
      2019 <a href="https://github.com/dongyuanxin/theme-ad/" target="_blank">Theme-AD</a>.
      Created by <a href="https://godbmw.com/" target="_blank">GodBMW</a>.
      All rights reserved.
    </div> -->
  </footer>
</div>
    <div id="site-layer" style="display:none;">
  <div class="site-layer-content">
    <div class="site-layer-header">
      <span class="site-layer-header-title" id="site-layer-title"></span>
      <i class="fa fa-close" id="site-layer-close"></i>
    </div>
    <div class="site-layer-body" id="site-layer-container">
      <div class="site-layer-input" id="site-layer-search" style="display: none;">
        <input type="text">
        <i class="fa fa-search"></i>
      </div>
      
        <div class="site-layer-reward" id="site-layer-reward" style="display: none;">
          
            <div>
              <img src="/blog/images/wechat.png" alt="WeChat">
              
                <p>WeChat</p>
              
            </div>
          
            <div>
              <img src="/blog/images/alipay.png" alt="AliPay">
              
                <p>AliPay</p>
              
            </div>
          
        </div>
      
      <div id="site-layer-welcome" style="display:none;"></div>
    </div>
  </div>
</div>
    

<div class="bottom-bar">

  <div class="bottom-bar-left">
<!--
    <a href="/blog/2019/05/26/%E3%80%90%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0%E3%80%91ES6%E7%9A%84%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/" data-enable="true">
      <i class="fa fa-arrow-left"></i>
    </a>
    <a href="/blog/2019/04/27/React-16-8-%E6%96%B0%E5%A2%9E%E7%89%B9%E6%80%A7-Hook/" data-enable="true">
      <i class="fa fa-arrow-right"></i>
    </a>
-->
  </div>

  
  
  
  <div class="bottom-bar-right">
    <a href="javascript:void(0);" data-enable="true" id="site-toc-show-btn">
      <i class="fa fa-bars"></i>
    </a>
    
      <a href="#site-comment" data-enable="true">
        <i class="fa fa-commenting"></i>
      </a>
    
    <a href="javascript:void(0);" id="site-toggle-share-btn">
      <i class="fa fa-share-alt"></i>
    </a>
    
    <a href="javascript:void(0);" id="back-top-btn">
      <i class="fa fa-chevron-up"></i>
    </a>
  </div>
</div>
    <div id="share-btn">
  
  
  
    <a id="share-btn-weibo" href="javascript:void(0);" target="_blank">
      <i class="fa fa-weibo"></i>
    </a>
  
  
    <a id="share-btn-qq" href="javascript:void(0);" target="_blank">
      <i class="fa fa-qq"></i>
    </a>
  
  
</div>
    





    
  </body>
</html>